using System;
using System.Collections.Generic;

namespace SmartSite.Frame
{
    public class ScaledUnsignedFloatField : ULongField, IValueField<float>
    {
        const int MaxCount = 32;
        readonly ushort ScaleFactor;

        public new float MaxValue { get => (float)base.MaxValue / ScaleFactor; }
        public new float MinValue { get => (float)base.MinValue; }

        public ScaledUnsignedFloatField(List<byte> buffer, BitUnit index, BitUnit count, ushort scaleFactor)
        : base(buffer, index, count)
        {
            CheckingCount(count, nameof(count));
            ScaleFactor = CheckingScaleFactor(scaleFactor, nameof(scaleFactor));
        }

        public ScaledUnsignedFloatField(IBytesBuffer buffer, BitUnit index, BitUnit count, ushort scaleFactor)
        : base(buffer, index, count)
        {
            CheckingCount(count, nameof(count));
            ScaleFactor = CheckingScaleFactor(scaleFactor, nameof(scaleFactor));
        }

        public ScaledUnsignedFloatField(IField field, BitUnit count, ushort scaleFactor)
        : base(field, count)
        {
            CheckingCount(count, nameof(count));
            ScaleFactor = CheckingScaleFactor(scaleFactor, nameof(scaleFactor));
        }

        static int CheckingCount(int count, string name)
        {
            if (count < 0 || count > MaxCount)
                throw new ArgumentOutOfRangeException(name);
            return count;
        }

        static ushort CheckingScaleFactor(ushort scaleFactor, string name)
        {
            if (scaleFactor == 0)
                throw new ArgumentOutOfRangeException(name);
            return scaleFactor;
        }

        public new float Value
        {
            get => (float)base.Value / ScaleFactor;
            set => base.Value = (ulong)((decimal)value * ScaleFactor);
        }
    }
}
